package com.uduemc.biso.node.core.common.utils;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.uduemc.biso.node.core.common.config.TRegexConfig;
import com.uduemc.biso.node.core.common.entities.ThemeObject;
import com.uduemc.biso.node.core.common.exception.TemplateException;
import com.uduemc.biso.node.core.node.extities.ClazzTemplateRegex;
import com.uduemc.biso.node.core.node.utils.LinkUtil;

import cn.hutool.core.util.StrUtil;

/**
 * 模板工具类用于操作模板时整体公共使用的静态方法
 * 
 * @author guanyi
 *
 */
public class ThemeUtil {

	private static final Logger logger = LoggerFactory.getLogger(ThemeUtil.class);

	// 获取 theme.json 文件内容
	public static String getThemeJson(String assetsPath, String templateNum) {
		StringBuilder filedir = new StringBuilder();
		filedir.append(assetsPath).append("/static/site/").append(templateNum).append("/").append("theme.json");
		String filePath = filedir.toString();
		String readFileToString = null;
		try {
			readFileToString = FileUtils.readFileToString(new File(filePath), "UTF-8");
		} catch (IOException e) {
			e.printStackTrace();
			throw new TemplateException("无法匹配到模板文件！ filePath: " + filePath);
		}
		return readFileToString;
	}

	public static List<String> getAllThemeJson(String assetsPath) {
		StringBuilder filedir = new StringBuilder();
		// 进入 static/site 目录
		StringBuilder siteDir = filedir.append(assetsPath).append("/static/site/");
		File siteDirFile = new File(siteDir.toString());
		if (!siteDirFile.isDirectory()) {
			return null;
		}
		String[] list = siteDirFile.list();
		ArrayList<String> theme = new ArrayList<>();// new ArrayList<>(Arrays.asList(list));
		for (int i = 0; i < list.length; i++) {
			String the = list[i];
			boolean file = new File(siteDir + the + "/theme.json").isFile();
			if (file) {
				theme.add(the);
			}
		}
		theme.sort((o1, o2) -> {
			Integer oi1 = null, oi2 = null;
			try {
				oi1 = Integer.valueOf(o1);
				oi2 = Integer.valueOf(o2);
			} catch (NumberFormatException e) {
			}
			if (oi1 != null && oi2 != null) {
				int diff = oi1 - oi2;
				if (diff > 0) {
					return 1;
				} else if (diff < 0) {
					return -1;
				}
			}
			return o1.compareTo(o2);
		});
		return theme;
	}

	public static String getFilePath(String path, String assetsPath) {
		return StrUtil.replace(path, "biso-assets", assetsPath);
	}

	public static String getThemeHead(ThemeObject themeObject, String templateName, String assetsPath) {
		Map<String, String> mapping = themeObject.getMapping();
		String path = mapping.get(templateName);
		String filePath = getFilePath(path, assetsPath);
		String readFileToString;
		try {
			readFileToString = FileUtils.readFileToString(new File(filePath), "UTF-8");
		} catch (IOException e) {
			e.printStackTrace();
			throw new TemplateException("无法匹配到模板文件！ filePath: " + filePath);
		}

		Pattern pattern = Pattern.compile("<head.*?>.*?</head>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
		Matcher matcher = pattern.matcher(readFileToString);

		if (matcher.find()) {
			return matcher.group(0);
		}

		throw new TemplateException("无法正确匹配模板的head体内容！filePath: " + filePath);
	}

	public static String getThemeBody(ThemeObject themeObject, String templateName, String assetsPath) {
		Map<String, String> mapping = themeObject.getMapping();
		String path = mapping.get(templateName);
		String filePath = getFilePath(path, assetsPath);
		String readFileToString;
		try {
			readFileToString = FileUtils.readFileToString(new File(filePath), "UTF-8");
		} catch (IOException e) {
			e.printStackTrace();
			throw new TemplateException("无法匹配到模板文件！ filePath: " + filePath);
		}

		Pattern pattern = Pattern.compile("<body.*?>.*?</body>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
		Matcher matcher = pattern.matcher(readFileToString);

		if (matcher.find()) {
			return matcher.group(0);
		}

		throw new TemplateException("无法正确匹配模板的body体内容！filePath: " + filePath);
	}

	public static String themeBodyAttr(String themeBody) {
		Pattern pattern = Pattern.compile("<body(.*?)>");
		Matcher matcher = pattern.matcher(themeBody);
		if (matcher.find()) {
			return matcher.group(1) == null ? "" : matcher.group(1);
		}
		return "";
	}

	public static String themeBodyReplace(String templateBody, List<ClazzTemplateRegex> listClazzTemplateRegex, String tempateName) {
		Pattern pattern = null;
		Matcher matcher = null;

		// 首先去除 body 标签
		pattern = Pattern.compile("<body.*?>(.*?)</body>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
		matcher = pattern.matcher(templateBody);

		if (matcher.find()) {
			if (matcher.group(1) != null) {
				templateBody = matcher.group(1);
			}
		}

		// 获取全部的正则匹配项
		List<ClazzTemplateRegex> regexes = listClazzTemplateRegex;
		for (ClazzTemplateRegex regex : regexes) {
			pattern = Pattern.compile(regex.getRegex().getRegex(), Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
			matcher = pattern.matcher(templateBody);
			while (matcher.find()) {
				String html = matcher.group(0);
				Class<?> forName = null;
				try {

					String clazzName = regex.getClazzName();
					if (StringUtils.hasText(clazzName)) {
						forName = Class.forName(clazzName);
					} else {
						String clazzNameForMap = regex.getClazzNameMap().get(tempateName);
						if (StringUtils.isEmpty(clazzNameForMap)) {
							throw new RuntimeException("未能找到 templateName 为：" + clazzNameForMap + " 的 clazzNameMap");
						}
						forName = Class.forName(clazzNameForMap);
					}
				} catch (ClassNotFoundException e2) {
					e2.printStackTrace();
				}
				if (forName == null) {
					continue;
				}
				Object instance = null;
				try {
					instance = forName.newInstance();
				} catch (InstantiationException e1) {
					e1.printStackTrace();
				} catch (IllegalAccessException e1) {
					e1.printStackTrace();
				}
				if (instance == null) {
					continue;
				}
				// 获取绑定在标签上的属性以及属性值
				Pattern patternAttr = Pattern.compile(regex.getRegex().getAttrRegex());
				Matcher matcherAttr = patternAttr.matcher(html);
				if (matcherAttr.find()) {
					String attributesString = matcherAttr.group(1);
					List<String> asList = Arrays.asList(StringUtils.trimWhitespace(attributesString).split(" "));
					// 反射调用的方法名称
					String methodName = null;
					for (String str : asList) {
						if (StringUtils.hasText(str)) {
							Pattern patternItem = Pattern.compile(TRegexConfig.ITEM_ATTRIBUTES_REGEX);
							Matcher matcherItem = patternItem.matcher(str);
							if (matcherItem.find()) {
								Method method;
								try {
									methodName = "set" + StringUtils.capitalize(matcherItem.group(1));
									method = forName.getMethod(methodName, String.class);
									try {
										method.invoke(instance, matcherItem.group(2));
									} catch (IllegalAccessException e) {
										e.printStackTrace();
									}
								} catch (NoSuchMethodException e) {
									logger.error("未能找到 " + regex.getClazzName() + " 方法：" + methodName + " args: " + matcherItem.group(2));
									e.printStackTrace();
								} catch (SecurityException e) {
									e.printStackTrace();
								} catch (IllegalArgumentException e) {
									e.printStackTrace();
								} catch (InvocationTargetException e) {
									e.printStackTrace();
								}
							}
						}
					}
				}
				Method method = null;
				try {
					method = forName.getMethod("html");

					String content = (String) method.invoke(instance);

					try {
						templateBody = StringUtils.replace(templateBody, matcher.group(), content);
					} catch (IllegalArgumentException e) {
						e.printStackTrace();
					}
				} catch (NoSuchMethodException e) {
					e.printStackTrace();
				} catch (SecurityException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e1) {
					e1.printStackTrace();
				} catch (IllegalArgumentException e1) {
					e1.printStackTrace();
				} catch (InvocationTargetException e1) {
					e1.printStackTrace();
				}
			}
		}

		return templateBody;
	}

	/**
	 * 获取 Include 加载的内容
	 * 
	 * @param path
	 * @param assetsPath
	 * @return
	 */
	public static String getInclude(String path, String assetsPath) {
		String filePath = getFilePath(path, assetsPath);
		String readFileToString;
		try {
			readFileToString = FileUtils.readFileToString(new File(filePath), "UTF-8");
		} catch (IOException e) {
			e.printStackTrace();
			throw new TemplateException("无法匹配到模板文件！ filePath: " + filePath);
		}

		return readFileToString;
	}

	/**
	 * 生成后台的 href 内容
	 * 
	 * @param hostId
	 * @param siteId
	 * @param href
	 * @return
	 */
	public static String getBackendHref(long hostId, long siteId, String href) {
		return LinkUtil.prefix(hostId, siteId, href);
	}

}
